<template>
  <el-popover
    placement="bottom"
    width="100%"
    :disabled="disabled || readonly"
    trigger="click"
    :value="visible"
    popper-class="c-org-select-popper"
    class="c-org-select-vertical"
    @show="fetchOrgList"
  >
    <el-input
      slot="reference"
      readonly
      :disabled="disabled"
      :placeholder="placeholder"
      :value="activeOrgLabel"
      class="ipt"
    >
      <i
        v-if="clearable"
        v-show="!!value"
        slot="suffix"
        class="el-icon-error clearable"
        @click.stop="clearValue"
      />
    </el-input>
    <el-input
      v-if="showSearch"
      v-model.trim="searchKey"
      size="small"
      placeholder=""
      @keyup.native.enter="handleSearch"
    >
      <el-button slot="append" icon="el-icon-search" @click="handleSearch" />
    </el-input>
    <el-tree
      v-if="loadTree"
      ref="tree"
      v-loading="isLoading"
      :data="orgTree"
      node-key="id"
      :props="{ label: 'name' }"
      default-expand-all
      :draggable="false"
      :expand-on-click-node="false"
      highlight-current
      :current-node-key="value"
      :filter-node-method="filterOrg"
      class="tree"
      @current-change="change"
    />
  </el-popover>
</template>

<script>
import findTargetFromTree from '@/utils/findTargetFromTree'
import { nativeWin, utils } from '@/utils'
import api from '@/api/index'
export default {
  props: {
    value: String,
    label: String,
    clearable: {
      type: Boolean,
      default: false
    },
    addRoot: {
      type: Boolean,
      default: false
    },
    showSearch: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: ''
    },
    disabledKeys: {
      type: Array,
      default: () => []
    },
    disabled: Boolean,
    readonly: Boolean
  },
  data () {
    return {
      searchKey: '',
      loadTree: true,
      isLoading: false,
      orgTree: [],
      manualSelectedOrg: null,
      visible: false
    }
  },
  computed: {
    activeOrgLabel () {
      const value = this.value
      const initLabel = this.label
      const manualSelectedOrg = this.manualSelectedOrg
      const orgTree = this.orgTree
      if (manualSelectedOrg) {
        const org = findTargetFromTree(orgTree, manualSelectedOrg.id, 'id')
        return org?.name ?? ''
      } else {
        return (!!value && initLabel) || ''
      }
    }
  },
  watch: {
    value (id) {
      if (typeof id === 'string') {
        const org = findTargetFromTree(this.orgTree, this.value, 'id')
        org && this.change(org || {}, null, true)
      } else {
        this.change({}, null, true)
        this.manualSelectedOrg = null
      }
      this.$nextTick(this.reload)
    }
  },
  created () {
    this.fetchOrgList()
  },
  methods: {
    clearValue () {
      this.change(null, null, true)
    },
    reload () {
      this.loadTree = !this.loadTree
      if (!this.loadTree) {
        this.$nextTick(this.reload)
      }
    },
    handleSearch () {
      this.$refs.tree.filter()
    },
    fetchOrgList () {
      this.isLoading = true
      api
        .organization()
        .then(res => {
          const ret = utils.toTree(res?._embedded?.organizations || [])
          if (this.addRoot) {
            this.orgTree = [
              {
                name: '根目录',
                id: '',
                children: ret
              }
            ]
          } else {
            this.orgTree = ret
          }
          this.isLoading = false
          const org = findTargetFromTree(this.orgTree, this.value, 'id')
          org && this.change(org || {}, null, true)
          this.handleDisabledNode(this.orgTree)
        })
        .catch(() => {
          this.isLoading = false
        })
    },
    handleDisabledNode (arr) {
      if (!this.disabledKeys) {
        return arr
      }
      arr && arr.length && 
        arr.forEach((itm, index) => {
          if (itm.id && this.disabledKeys.includes(itm.id)) {
            arr.splice(index, 1)
          }
          itm.children && (itm.children = this.handleDisabledNode(itm.children))
        })
      return arr
    },
    filterOrg (_, data) {
      return (
        !this.searchKey ||
        (data.name || '').toLowerCase().includes(this.searchKey.toLowerCase())
      )
    },
    change (data, _, isNotUserTrigger) {
      console.log('org change', data, isNotUserTrigger)
      this.$emit('input', data?.id)
      this.$emit(
        'change',
        data && {
          ...data
        }
      )
      if (!isNotUserTrigger) {
        nativeWin.document.body.click()
      }
      this.manualSelectedOrg = data
    }
  }
}
</script>

<style lang="scss" scoped>
.c-org-select-vertical {
  ::v-deep .el-popover__reference {
    .clearable {
      cursor: pointer;
      opacity: 0;
    }
    &:hover {
      .clearable {
        opacity: 1;
      }
    }
  }
}
</style>

<style lang="scss">
div.c-org-select-popper {
  min-width: 200px;
  .tree {
    max-height: 400px;
    overflow: auto;
  }
}
</style>
